/* CPP Assignemnt 3 (COSC1152-2011-S2)
 * Elliott O'Dea-Joyce s3074110@student.rmit.edu.au
 * Ross Nye s9455459@student.rmit.edu.au
 *
 * This code written by Jesse Archer
 */


#include "utils.h"

// Stack is used so that a beginTimer/endTimer pair can be called inside another
// beginTimer/endTimer pair
std::stack<clock_t> Timer::startTimes;
std::stack<clock_t> Timer::endTimes;

void beginTimer()
{
	Timer::startTimes.push(clock());
}

void endTimer()
{
	Timer::endTimes.push(clock());
}

float getTime()
{
	clock_t startTime = Timer::startTimes.top(); Timer::startTimes.pop();
	clock_t endTime = Timer::endTimes.top(); Timer::endTimes.pop();
	clock_t diff = endTime - startTime;
	return ((float)diff / (float)CLOCKS_PER_SEC) * 1000.0f;
}

// Basically some C++ versions of atoi/atof, if you're used to using those
int toInt(const std::string &str)
{
	int i = 0;
	std::istringstream iss(str);
	if ((iss >> i).fail())
	{
		throw std::runtime_error("Unable to convert str to int");
	}

	return i;
}

float toFloat(const std::string &str)
{
	float f = 0.0f;
	std::istringstream iss(str);
	if ((iss >> f).fail())
	{
		throw std::runtime_error("Unable to convert str to int");
	}

	return f;
}

// There are a lot of different ways to tokenize strings in C++, the easiest way
// is to not bother with tokenizing at all and just read the data directly from
// the stream and check if it failed, this way is much slower but for anyone
// used to strtok, this would be a rough C++ equivalent
std::vector<std::string> tokenize(std::string str, std::string tokens)
{
	for (size_t i = 0; i < str.length(); i++)
		for (size_t j = 0; j < tokens.length(); j++)
			if (str[i] == tokens[j])
				str[i] = ' ';

	std::stringstream sstr(str);

	std::istream_iterator<std::string> it(sstr);
	std::istream_iterator<std::string> end;

	std::vector<std::string> results(it, end);
	return results;
}

// This function actually returns the length squared to avoid performing an sqrt
// operation, so I renamed it to getLengthSq
#if 0
float getLengthSq(Point p1, Point p2)
{
	return pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2);
}
#endif
